package com.poi.demopoi.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @title: LoggerUtil
 * @package: com.xyj.common.utils
 * @description: 日志处理通用类
 * @anther: dongzhanbiao
 * @date: 2020-02-25  5:21 下午
 */
public class LoggerUtil {

    /** 缓存日志前缀 */
    private static Map<String, String> prefixDB = new ConcurrentHashMap<String, String>();

    static {
    }

    /**
     * INFO日志
     * @param clazz 调用类
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void info(Class<?> clazz, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isInfoEnabled())
            logger.info(logPrefix(clazz) + MessageFormat.format(format, args));
    }

    /**
     * INFO日志
     * @param className 类名称
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void info(String className, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(className);
        if(logger.isInfoEnabled())
            logger.info(MessageFormat.format(format, args));
    }

    /**
     * INFO日志
     * @param clazz 调用类
     * @param message 日志内容
     */
    public static void info(Class<?> clazz, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isInfoEnabled())
            logger.info(logPrefix(clazz) + message);
    }

    /**
     * INFO日志
     * @param clazz 调用类
     * @param cause 抛出的异常
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void info(Class<?> clazz, Throwable cause, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isInfoEnabled())
            logger.info(logPrefix(clazz) + MessageFormat.format(format, args),  cause);
    }

    /**
     * INFO日志
     * @param clazz 调用类
     * @param cause 抛出的异常
     * @param message 日志内容
     */
    public static void info(Class<?> clazz, Throwable cause, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isInfoEnabled())
            logger.info(logPrefix(clazz) + message, cause);
    }

    /**
     * DEBUG日志
     * @param clazz 调用类
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void debug(Class<?> clazz, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isDebugEnabled())
            logger.debug(logPrefix(clazz) + MessageFormat.format(format, args));
    }

    /**
     * DEBUG日志
     * @param clazz 调用类
     * @param message 消息内容
     */
    public static void debug(Class<?> clazz, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isDebugEnabled())
            logger.debug(logPrefix(clazz) + message);
    }

    /**
     * DEBUG日志
     * @param clazz 调用类
     * @param message 消息内容
     */
    public static void debug(String className, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(className);
        if(logger.isDebugEnabled())
            logger.debug(MessageFormat.format(format, args));
    }

    /**
     * WARN日志
     * @param clazz 调用类
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void warn(Class<?> clazz, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isWarnEnabled())
            logger.warn(logPrefix(clazz) + MessageFormat.format(format, args));
    }

    /**
     * WARN日志
     * @param clazz 调用类
     * @param message 日志内容
     */
    public static void warn(Class<?> clazz, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isWarnEnabled())
            logger.warn(logPrefix(clazz) + message);
    }

    /**
     * WARN日志
     * @param clazz 调用类
     * @param cause 抛出的异常
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void warn(Class<?> clazz, Throwable cause, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isWarnEnabled())
            logger.warn(logPrefix(clazz) + MessageFormat.format(format, args), cause);
    }

    /**
     * WARN日志
     * @param clazz 调用类
     * @param cause 抛出异常
     * @param message 日志内容
     */
    public static void warn(Class<?> clazz, Throwable cause, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if(logger.isWarnEnabled())
            logger.warn(logPrefix(clazz) + message, cause);
    }

    /**
     * ERROR日志
     * @param clazz 调用类
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void error(Class<?> clazz, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        logger.error(logPrefix(clazz) + MessageFormat.format(format, args));
    }

    /**
     * ERROR日志
     * @param className 调用类名
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void error(String className, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(className);
        logger.error(MessageFormat.format(format, args));
    }

    /**
     * ERROR日志
     * @param clazz 调用类
     * @param message 日志内容
     */
    public static void error(Class<?> clazz, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        logger.error(logPrefix(clazz) + message);
    }

    /**
     * ERROR日志
     * @param className 调用类名
     * @param message 日志内容
     */
    public static void error(String className, String message) {
        Logger logger = LoggerFactory.getLogger(className);
        logger.error(message);
    }

    /**
     * ERROR日志
     * @param clazz 调用类
     * @param cause 抛出的异常
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void error(Class<?> clazz, Throwable cause, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        logger.error(logPrefix(clazz) + MessageFormat.format(format, args), cause);
    }

    /**
     * ERROR日志
     * @param className 调用类
     * @param cause 抛出的异常
     * @param format 日志格式，可以不包含参数
     * @param args 日志格式中包含的参数对应值
     */
    public static void error(String className, Throwable cause, String format, Object... args) {
        Logger logger = LoggerFactory.getLogger(className);
        logger.error(MessageFormat.format(format, args), cause);
    }

    /**
     * ERROR日志
     * @param clazz 调用类
     * @param cause 抛出异常
     * @param message 日志内容
     */
    public static void error(Class<?> clazz, Throwable cause, String message) {
        Logger logger = LoggerFactory.getLogger(clazz);
        logger.error(logPrefix(clazz) + message, cause);
    }

    private static ThreadLocal<String> identity = new ThreadLocal<String>() {

        /**
         * @see ThreadLocal#initialValue()
         */
        @Override
        protected String initialValue() {
            return UUID.randomUUID().toString();
        }

    };

    /**
     * 开始日志流程
     */
    public static void beginLog() {
        identity.set(UUID.randomUUID().toString());
    }

    /**
     * 多线程时，传入的唯一标识
     * @param uuid 唯一标识
     */
    public static void beginLog(String uuid) {
        identity.set(uuid);
    }

    /**
     * 停止日志流程
     */
    public static void endLog() {
        identity.remove();
    }

    private static String logPrefix(Class<?> clazz) {
//        StringBuilder sb = new StringBuilder();
//        sb.append("#UUID[");
//        sb.append(identity.get());
//        String prefix = getPrefixFromDB(clazz.getCanonicalName());
//        if(prefix != null) {
//            sb.append("~");
//            sb.append(prefix);
//        }
//        sb.append("]#");
//        return sb.toString();
        return StringUtils.EMPTY;
    }

    private static String getPrefixFromDB(String source) {
        if(prefixDB.size() == 0 || StringUtils.isEmpty(source))
            return null;
        for(Map.Entry<String, String> entry : prefixDB.entrySet()) {
            String key = entry.getKey();
            if(source.indexOf(key) >= 0)
                return entry.getValue();
        }
        return null;
    }
}
